{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "d0cefea1-f982-4bb1-b691-27a855bfdccb",
      "metadata": {
        "id": "d0cefea1-f982-4bb1-b691-27a855bfdccb"
      },
      "source": [
        "# Dynamic breakpoints\n",
        "\n",
        "## Review\n",
        "\n",
        "We discussed motivations for human-in-the-loop:\n",
        "\n",
        "(1) `Approval` - We can interrupt our agent, surface state to a user, and allow the user to accept an action\n",
        "\n",
        "(2) `Debugging` - We can rewind the graph to reproduce or avoid issues\n",
        "\n",
        "(3) `Editing` - You can modify the state\n",
        "\n",
        "We covered breakpoints as a general way to stop the graph at specific steps, which enables use-cases like `Approval`\n",
        "\n",
        "We also showed how to edit graph state, and introduce human feedback.\n",
        "\n",
        "## Goals\n",
        "\n",
        "Breakpoints are set by the developer on a specific node during graph compilation.\n",
        "\n",
        "But, sometimes it is helpful to allow the graph **dynamically interrupt** itself!\n",
        "\n",
        "This is an internal breakpoint, and [can be achieved using `NodeInterrupt`](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/dynamic_breakpoints/#run-the-graph-with-dynamic-interrupt).\n",
        "\n",
        "This has a few specific benefits:\n",
        "\n",
        "(1) you can do it conditionally (from inside a node based on developer-defined logic).\n",
        "\n",
        "(2) you can communicate to the user why its interrupted (by passing whatever you want to the `NodeInterrupt`).\n",
        "\n",
        "Let's create a graph where a `NodeInterrupt` is thrown based upon length of the input."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "387d8d87-598a-485a-a99f-a9270a7c2e73",
      "metadata": {
        "id": "387d8d87-598a-485a-a99f-a9270a7c2e73"
      },
      "outputs": [],
      "source": [
        "%%capture --no-stderr\n",
        "%pip install --quiet -U langgraph langgraph_sdk"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "2ea38ae0",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "2ea38ae0",
        "outputId": "576239d9-538f-4319-abfa-a90a5b8bda49"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "env: LANGCHAIN_API_KEY=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\n"
          ]
        }
      ],
      "source": [
        "import os\n",
        "from google.colab import userdata\n",
        "\n",
        "%env LANGCHAIN_API_KEY = {userdata.get('LANGCHAIN_API_KEY')}\n",
        "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
        "os.environ[\"LANGCHAIN_PROJECT\"] = \"langchain-academy\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "6248f166-2013-445a-b4ae-1fb7b92f8c32",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 449
        },
        "id": "6248f166-2013-445a-b4ae-1fb7b92f8c32",
        "outputId": "d3dc9b3c-8152-48c0-f9b7-0703b884b5c9"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/jpeg": "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\n",
            "text/plain": [
              "<IPython.core.display.Image object>"
            ]
          },
          "metadata": {}
        }
      ],
      "source": [
        "from IPython.display import Image, display\n",
        "\n",
        "from typing_extensions import TypedDict\n",
        "from langgraph.checkpoint.memory import MemorySaver\n",
        "from langgraph.errors import NodeInterrupt\n",
        "from langgraph.graph import START, END, StateGraph\n",
        "from langgraph.graph.state import CompiledStateGraph\n",
        "\n",
        "class State(TypedDict):\n",
        "    input: str\n",
        "\n",
        "def step_1(state: State) -> State:\n",
        "    print(\"---Step 1---\")\n",
        "    return state\n",
        "\n",
        "def step_2(state: State) -> State:\n",
        "    # Let's optionally raise a NodeInterrupt if the length of the input is longer than 5 characters\n",
        "    if len(state['input']) > 5:\n",
        "        raise NodeInterrupt(f\"Received input that is longer than 5 characters: {state['input']}\")\n",
        "\n",
        "    print(\"---Step 2---\")\n",
        "    return state\n",
        "\n",
        "def step_3(state: State) -> State:\n",
        "    print(\"---Step 3---\")\n",
        "    return state\n",
        "\n",
        "builder: StateGraph = StateGraph(State)\n",
        "builder.add_node(\"step_1\", step_1)\n",
        "builder.add_node(\"step_2\", step_2)\n",
        "builder.add_node(\"step_3\", step_3)\n",
        "builder.add_edge(START, \"step_1\")\n",
        "builder.add_edge(\"step_1\", \"step_2\")\n",
        "builder.add_edge(\"step_2\", \"step_3\")\n",
        "builder.add_edge(\"step_3\", END)\n",
        "\n",
        "# Set up memory\n",
        "memory: MemorySaver = MemorySaver()\n",
        "\n",
        "# Compile the graph with memory\n",
        "graph: CompiledStateGraph = builder.compile(checkpointer=memory)\n",
        "\n",
        "# View\n",
        "display(Image(graph.get_graph().draw_mermaid_png()))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b2c6e5c8-0556-43d1-9eef-b3af32728f74",
      "metadata": {
        "id": "b2c6e5c8-0556-43d1-9eef-b3af32728f74"
      },
      "source": [
        "Let's run the graph with an input that's longer than 5 characters."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "de73c9ce-ccc5-4ffd-8d82-7018364e7c4f",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "de73c9ce-ccc5-4ffd-8d82-7018364e7c4f",
        "outputId": "8c892fe7-d186-4301-c20d-48dd951cab35"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'input': 'hello world'}\n",
            "---Step 1---\n",
            "{'input': 'hello world'}\n"
          ]
        }
      ],
      "source": [
        "initial_input = {\"input\": \"hello world\"}\n",
        "thread_config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
        "\n",
        "# Run the graph until the first interruption\n",
        "for event in graph.stream(initial_input, thread_config, stream_mode=\"values\"):\n",
        "    print(event)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "da79063f-5b67-49dd-8ef0-3eae4c480cb5",
      "metadata": {
        "id": "da79063f-5b67-49dd-8ef0-3eae4c480cb5"
      },
      "source": [
        "If we inspect the graph state at this point, we the node set to execute next (`step_2`).\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "34706f0d-379b-4236-a42e-c8e52b27fb22",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "34706f0d-379b-4236-a42e-c8e52b27fb22",
        "outputId": "e1a6fcd8-52d9-42f0-a459-777bc7f0911a"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "('step_2',)\n"
          ]
        }
      ],
      "source": [
        "state = graph.get_state(thread_config)\n",
        "print(state.next)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3ed78755-f1e8-4c66-a4f8-a7ccff472c91",
      "metadata": {
        "id": "3ed78755-f1e8-4c66-a4f8-a7ccff472c91"
      },
      "source": [
        "We can see that the `Interrupt` is logged to state."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "93815a05-819a-4050-8834-73236fa910dc",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "93815a05-819a-4050-8834-73236fa910dc",
        "outputId": "d7f4e10c-e144-45e7-807a-66925624c3dc"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "(PregelTask(id='126c7dfc-734f-09c3-e484-05fa7d256287', name='step_2', path=('__pregel_pull', 'step_2'), error=None, interrupts=(Interrupt(value='Received input that is longer than 5 characters: hello world', when='during'),), state=None),)\n"
          ]
        }
      ],
      "source": [
        "print(state.tasks)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "27d74573-b62c-4ac1-a142-d04c2dccfd08",
      "metadata": {
        "id": "27d74573-b62c-4ac1-a142-d04c2dccfd08"
      },
      "source": [
        "We can try to resume the graph from the breakpoint.\n",
        "\n",
        "But, this just re-runs the same node!\n",
        "\n",
        "Unless state is changed we will be stuck here."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "b735875e-62c6-4253-ba85-7ccf93a353b4",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "b735875e-62c6-4253-ba85-7ccf93a353b4",
        "outputId": "d2715ac8-983c-4a56-9654-490b5b0dc460"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'input': 'hello world'}\n"
          ]
        }
      ],
      "source": [
        "for event in graph.stream(None, thread_config, stream_mode=\"values\"):\n",
        "    print(event)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "1e3bc5e3-7a2f-49a1-8bdc-fd3597bd5fae",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1e3bc5e3-7a2f-49a1-8bdc-fd3597bd5fae",
        "outputId": "f5185c6c-5dd6-4625-9159-2f7c1ea6714a"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "('step_2',)\n"
          ]
        }
      ],
      "source": [
        "state = graph.get_state(thread_config)\n",
        "print(state.next)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "79ab61de-5c3f-44a5-b417-e36b1a2f26dd",
      "metadata": {
        "id": "79ab61de-5c3f-44a5-b417-e36b1a2f26dd"
      },
      "source": [
        "Now, we can update state."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "6f08dff4-3399-46de-a9ba-ba89b8cdb61e",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6f08dff4-3399-46de-a9ba-ba89b8cdb61e",
        "outputId": "7bd31b22-9102-46c3-806f-9d3ce05c7bf7"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'configurable': {'thread_id': '1',\n",
              "  'checkpoint_ns': '',\n",
              "  'checkpoint_id': '1ef7bea4-2786-6c89-8005-db61c833596a'}}"
            ]
          },
          "metadata": {},
          "execution_count": 12
        }
      ],
      "source": [
        "graph.update_state(\n",
        "    thread_config,\n",
        "    {\"input\": \"hi\"},\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "4cb3f62b-fccd-47c3-af1e-541969e4d804",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "4cb3f62b-fccd-47c3-af1e-541969e4d804",
        "outputId": "d323abe8-53ba-45ea-9b5c-68b4354e0b8b"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'input': 'hi'}\n",
            "---Step 2---\n",
            "{'input': 'hi'}\n",
            "---Step 3---\n",
            "{'input': 'hi'}\n"
          ]
        }
      ],
      "source": [
        "for event in graph.stream(None, thread_config, stream_mode=\"values\"):\n",
        "    print(event)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "76e3dea8-8270-42c7-8d24-606b79b9c6aa",
      "metadata": {
        "id": "76e3dea8-8270-42c7-8d24-606b79b9c6aa"
      },
      "source": [
        "### Usage with LangGraph API\n",
        "\n",
        "--\n",
        "\n",
        "**⚠️ DISCLAIMER**\n",
        "\n",
        "*Running Studio currently requires a Mac. If you are not using a Mac, then skip this step.*\n",
        "\n",
        "*Also, if you are running this notebook in CoLab, then skip this step.*\n",
        "\n",
        "--\n",
        "\n",
        "We can run the above graph in Studio with `module-3/studio/dynamic_breakpoints.py`.\n",
        "\n",
        "![Screenshot 2024-08-27 at 2.02.20 PM.png](https://cdn.prod.website-files.com/65b8cd72835ceeacd4449a53/66dbaedf43c3d4df239c589e_dynamic-breakpoints1.png)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "be02c417-5adc-4789-aa90-02fd2312eb53",
      "metadata": {
        "id": "be02c417-5adc-4789-aa90-02fd2312eb53"
      },
      "outputs": [],
      "source": [
        "import platform\n",
        "\n",
        "if 'google.colab' in str(get_ipython()) or platform.system() != 'Darwin':\n",
        "    raise Exception(\"Unfortunately LangGraph Studio is currently not supported on Google Colab or requires a Mac\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2390ff2e-6b1a-4c6e-b0ce-debd45085dc8",
      "metadata": {
        "id": "2390ff2e-6b1a-4c6e-b0ce-debd45085dc8"
      },
      "source": [
        "We connect to it via the SDK."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "4696327d",
      "metadata": {
        "id": "4696327d"
      },
      "outputs": [],
      "source": [
        "from langgraph_sdk import get_client\n",
        "\n",
        "# Replace this with the URL of your own deployed graph\n",
        "URL = \"https://cardiff-rivers-timothy-supply.trycloudflare.com\"\n",
        "client = get_client(url=URL)\n",
        "\n",
        "# Search all hosted graphs\n",
        "assistants = await client.assistants.search()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "8cb892cb-c79c-46bb-820b-d0479e71c5c4",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8cb892cb-c79c-46bb-820b-d0479e71c5c4",
        "outputId": "8d811cea-0eb1-4eb5-c0bc-ab57ba310b7a"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Receiving new event of type: metadata...\n",
            "{'run_id': '1ef7bea5-52e3-64f2-b9c2-9c4247af6f1b', 'attempt': 1}\n",
            "\n",
            "\n",
            "\n",
            "Receiving new event of type: values...\n",
            "{'input': 'hello world'}\n",
            "\n",
            "\n",
            "\n",
            "Receiving new event of type: values...\n",
            "{'input': 'hello world'}\n",
            "\n",
            "\n",
            "\n"
          ]
        }
      ],
      "source": [
        "thread = await client.threads.create()\n",
        "input_dict = {\"input\": \"hello world\"}\n",
        "\n",
        "async for chunk in client.runs.stream(\n",
        "    thread[\"thread_id\"],\n",
        "    assistant_id=\"dynamic_breakpoints\",\n",
        "    input=input_dict,\n",
        "    stream_mode=\"values\",):\n",
        "\n",
        "    print(f\"Receiving new event of type: {chunk.event}...\")\n",
        "    print(chunk.data)\n",
        "    print(\"\\n\\n\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "0ba7d9da",
      "metadata": {
        "id": "0ba7d9da"
      },
      "outputs": [],
      "source": [
        "current_state = await client.threads.get_state(thread['thread_id'])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "9610fc2b-ae39-4ffa-84af-b049e7d22cd6",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "9610fc2b-ae39-4ffa-84af-b049e7d22cd6",
        "outputId": "d24d97eb-8eb6-46c2-b724-949f9bcb503d"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "['step_2']"
            ]
          },
          "metadata": {},
          "execution_count": 17
        }
      ],
      "source": [
        "current_state['next']"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "1e880cf0-18b1-4f7b-a770-24d45dd22757",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1e880cf0-18b1-4f7b-a770-24d45dd22757",
        "outputId": "80f2e0f6-9af2-4d18-ab62-7101fad64a97"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'checkpoint': {'thread_id': 'a394a61a-ec3a-4769-8d53-617414ed175f',\n",
              "  'checkpoint_ns': '',\n",
              "  'checkpoint_id': '1ef7bea6-a84b-6ec4-8002-738a0528c65e'},\n",
              " 'configurable': {'thread_id': 'a394a61a-ec3a-4769-8d53-617414ed175f',\n",
              "  'checkpoint_ns': '',\n",
              "  'checkpoint_id': '1ef7bea6-a84b-6ec4-8002-738a0528c65e'},\n",
              " 'checkpoint_id': '1ef7bea6-a84b-6ec4-8002-738a0528c65e'}"
            ]
          },
          "metadata": {},
          "execution_count": 18
        }
      ],
      "source": [
        "await client.threads.update_state(thread['thread_id'], {\"input\": \"hi!\"})"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "16dc65b9-95c0-46eb-9f73-da0a35e70034",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "16dc65b9-95c0-46eb-9f73-da0a35e70034",
        "outputId": "0c2e10ae-5bb8-445f-8ac9-1bf54ca136fb"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Receiving new event of type: metadata...\n",
            "{'run_id': '1ef7bea7-08b9-6d5f-b509-1391f5ab13a0', 'attempt': 1}\n",
            "\n",
            "\n",
            "\n",
            "Receiving new event of type: values...\n",
            "{'input': 'hi!'}\n",
            "\n",
            "\n",
            "\n",
            "Receiving new event of type: values...\n",
            "{'input': 'hi!'}\n",
            "\n",
            "\n",
            "\n",
            "Receiving new event of type: values...\n",
            "{'input': 'hi!'}\n",
            "\n",
            "\n",
            "\n"
          ]
        }
      ],
      "source": [
        "async for chunk in client.runs.stream(\n",
        "    thread[\"thread_id\"],\n",
        "    assistant_id=\"dynamic_breakpoints\",\n",
        "    input=None,\n",
        "    stream_mode=\"values\",):\n",
        "\n",
        "    print(f\"Receiving new event of type: {chunk.event}...\")\n",
        "    print(chunk.data)\n",
        "    print(\"\\n\\n\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "5f662b10-ad4c-45c7-a420-ded8ccae8faa",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "5f662b10-ad4c-45c7-a420-ded8ccae8faa",
        "outputId": "b7b63ce3-3f94-456c-a070-5c22c5da48e1"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'values': {'input': 'hi!'},\n",
              " 'next': [],\n",
              " 'tasks': [],\n",
              " 'metadata': {'step': 4,\n",
              "  'run_id': '1ef7bea7-08b9-6d5f-b509-1391f5ab13a0',\n",
              "  'source': 'loop',\n",
              "  'writes': {'step_3': {'input': 'hi!'}},\n",
              "  'parents': {},\n",
              "  'user_id': '',\n",
              "  'graph_id': 'dynamic_breakpoints',\n",
              "  'thread_id': 'a394a61a-ec3a-4769-8d53-617414ed175f',\n",
              "  'created_by': 'system',\n",
              "  'run_attempt': 1,\n",
              "  'assistant_id': '6f6fce9a-b777-529d-9699-dd340ddec86c',\n",
              "  'x-forwarded-for': '34.48.111.248',\n",
              "  'x-forwarded-proto': 'https'},\n",
              " 'created_at': '2024-09-26T09:33:51.352382+00:00',\n",
              " 'checkpoint': {'thread_id': 'a394a61a-ec3a-4769-8d53-617414ed175f',\n",
              "  'checkpoint_ns': '',\n",
              "  'checkpoint_id': '1ef7bea7-09aa-6f3c-8004-0d63c32e8a69'},\n",
              " 'parent_checkpoint': {'thread_id': 'a394a61a-ec3a-4769-8d53-617414ed175f',\n",
              "  'checkpoint_ns': '',\n",
              "  'checkpoint_id': '1ef7bea7-099d-621f-8003-de7c4b415319'},\n",
              " 'checkpoint_id': '1ef7bea7-09aa-6f3c-8004-0d63c32e8a69',\n",
              " 'parent_checkpoint_id': '1ef7bea7-099d-621f-8003-de7c4b415319'}"
            ]
          },
          "metadata": {},
          "execution_count": 20
        }
      ],
      "source": [
        "current_state = await client.threads.get_state(thread['thread_id'])\n",
        "current_state"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "873b3696-df61-4f2e-94d8-089b7072aafa",
      "metadata": {
        "id": "873b3696-df61-4f2e-94d8-089b7072aafa"
      },
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3 (ipykernel)",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.12.4"
    },
    "colab": {
      "provenance": []
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}